/*
 * Copyright 2025-2026 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.ai.mcp.sample.server;

import java.util.HashMap;
import java.util.Map;
import java.text.DecimalFormat;

import org.springframework.ai.tool.annotation.Tool;
import org.springframework.ai.tool.annotation.ToolParam;
import org.springframework.stereotype.Service;

/**
 * 简单计算工具服务
 * 提供基础计算、单位转换和常用信息查询功能
 */
@Service
public class SimpleCalculatorService {

    private final DecimalFormat decimalFormat = new DecimalFormat("#.##");
    private final Map<String, String> currencySymbols = new HashMap<>();
    
    public SimpleCalculatorService() {
        // 初始化常用货币符号
        currencySymbols.put("CNY", "¥");
        currencySymbols.put("USD", "$");
        currencySymbols.put("EUR", "€");
        currencySymbols.put("GBP", "£");
        currencySymbols.put("JPY", "¥");
    }

    /**
     * 执行基本数学运算
     * 
     * @param num1 第一个数字
     * @param num2 第二个数字
     * @param operation 运算类型（加、减、乘、除）
     * @return 计算结果
     */
    @Tool(description = "执行基本数学运算")
    public String calculate(
            @ToolParam(description = "第一个数字") double num1,
            @ToolParam(description = "第二个数字") double num2,
            @ToolParam(description = "运算类型（加、减、乘、除）") String operation) {
        
        double result;
        String operationSymbol;
        
        switch (operation.toLowerCase().trim()) {
            case "加":
            case "add":
            case "+":
                result = num1 + num2;
                operationSymbol = "+";
                break;
            case "减":
            case "subtract":
            case "-":
                result = num1 - num2;
                operationSymbol = "-";
                break;
            case "乘":
            case "multiply":
            case "*":
                result = num1 * num2;
                operationSymbol = "×";
                break;
            case "除":
            case "divide":
            case "/":
                if (num2 == 0) {
                    return "错误：除数不能为零";
                }
                result = num1 / num2;
                operationSymbol = "÷";
                break;
            default:
                return "错误：不支持的运算类型。请使用：加、减、乘、除";
        }
        
        return String.format("""
                计算结果:
                %.2f %s %.2f = %.2f
                """, 
                num1, operationSymbol, num2, result);
    }

    /**
     * 温度单位转换
     * 
     * @param temperature 温度值
     * @param fromUnit 原始单位（摄氏度、华氏度、开尔文）
     * @param toUnit 目标单位（摄氏度、华氏度、开尔文）
     * @return 转换结果
     */
    @Tool(description = "温度单位转换")
    public String convertTemperature(
            @ToolParam(description = "温度值") double temperature,
            @ToolParam(description = "原始单位（摄氏度、华氏度、开尔文）") String fromUnit,
            @ToolParam(description = "目标单位（摄氏度、华氏度、开尔文）") String toUnit) {
        
        // 先转换为摄氏度作为中间单位
        double celsiusTemp;
        switch (fromUnit.toLowerCase().trim()) {
            case "摄氏度":
            case "celsius":
            case "c":
                celsiusTemp = temperature;
                break;
            case "华氏度":
            case "fahrenheit":
            case "f":
                celsiusTemp = (temperature - 32) * 5 / 9;
                break;
            case "开尔文":
            case "kelvin":
            case "k":
                celsiusTemp = temperature - 273.15;
                break;
            default:
                return "错误：不支持的温度单位。请使用：摄氏度、华氏度、开尔文";
        }
        
        // 从摄氏度转换为目标单位
        double result;
        String resultUnit;
        switch (toUnit.toLowerCase().trim()) {
            case "摄氏度":
            case "celsius":
            case "c":
                result = celsiusTemp;
                resultUnit = "°C";
                break;
            case "华氏度":
            case "fahrenheit":
            case "f":
                result = celsiusTemp * 9 / 5 + 32;
                resultUnit = "°F";
                break;
            case "开尔文":
            case "kelvin":
            case "k":
                result = celsiusTemp + 273.15;
                resultUnit = "K";
                break;
            default:
                return "错误：不支持的温度单位。请使用：摄氏度、华氏度、开尔文";
        }
        
        String fromUnitSymbol = getTemperatureUnitSymbol(fromUnit);
        
        return String.format("""
                温度转换结果:
                %.2f%s = %.2f%s
                """, 
                temperature, fromUnitSymbol, result, resultUnit);
    }

    /**
     * 货币换算
     * 
     * @param amount 金额
     * @param fromCurrency 原始货币（CNY、USD、EUR、GBP、JPY）
     * @param toCurrency 目标货币（CNY、USD、EUR、GBP、JPY）
     * @return 换算结果
     */
    @Tool(description = "货币换算（使用模拟汇率）")
    public String convertCurrency(
            @ToolParam(description = "金额") double amount,
            @ToolParam(description = "原始货币（CNY、USD、EUR、GBP、JPY）") String fromCurrency,
            @ToolParam(description = "目标货币（CNY、USD、EUR、GBP、JPY）") String toCurrency) {
        
        // 模拟汇率（相对于CNY）
        Map<String, Double> exchangeRates = new HashMap<>();
        exchangeRates.put("CNY", 1.0);
        exchangeRates.put("USD", 0.14);
        exchangeRates.put("EUR", 0.13);
        exchangeRates.put("GBP", 0.11);
        exchangeRates.put("JPY", 21.0);
        
        fromCurrency = fromCurrency.toUpperCase().trim();
        toCurrency = toCurrency.toUpperCase().trim();
        
        if (!exchangeRates.containsKey(fromCurrency)) {
            return "错误：不支持的原始货币。支持的货币：CNY、USD、EUR、GBP、JPY";
        }
        
        if (!exchangeRates.containsKey(toCurrency)) {
            return "错误：不支持的目标货币。支持的货币：CNY、USD、EUR、GBP、JPY";
        }
        
        // 先转换为CNY
        double amountInCNY = amount / exchangeRates.get(fromCurrency);
        
        // 再从CNY转换为目标货币
        double result = amountInCNY * exchangeRates.get(toCurrency);
        
        String fromSymbol = currencySymbols.getOrDefault(fromCurrency, fromCurrency);
        String toSymbol = currencySymbols.getOrDefault(toCurrency, toCurrency);
        
        return String.format("""
                货币换算结果 (使用模拟汇率):
                %s%.2f = %s%.2f
                
                注意：这是基于模拟汇率的计算结果，仅供参考。
                实际汇率会根据市场波动而变化。
                """, 
                fromSymbol, amount, toSymbol, result);
    }

    /**
     * 计算BMI指数
     * 
     * @param weight 体重（千克）
     * @param height 身高（米）
     * @return BMI计算结果和健康建议
     */
    @Tool(description = "计算BMI指数")
    public String calculateBMI(
            @ToolParam(description = "体重（千克）") double weight,
            @ToolParam(description = "身高（米）") double height) {
        
        if (height <= 0 || weight <= 0) {
            return "错误：身高和体重必须为正数";
        }
        
        double bmi = weight / (height * height);
        String category;
        String advice;
        
        if (bmi < 18.5) {
            category = "偏瘦";
            advice = "建议适当增加营养摄入，保持均衡饮食，增加适量运动以增强体质。";
        } else if (bmi < 24) {
            category = "正常";
            advice = "恭喜！您的体重处于健康范围，建议继续保持健康的生活方式。";
        } else if (bmi < 28) {
            category = "偏胖";
            advice = "建议控制饮食热量摄入，增加有氧运动，保持健康生活习惯。";
        } else {
            category = "肥胖";
            advice = "建议咨询医生或营养师，制定合理的减重计划，注意饮食控制和规律运动。";
        }
        
        return String.format("""
                BMI计算结果:
                您的BMI指数: %.2f
                体重状态: %s
                
                健康建议:
                %s
                
                注意：BMI只是健康评估的一个参考指标，不能完全代表健康状况。
                如有健康问题，请咨询专业医疗人员。
                """, 
                bmi, category, advice);
    }

    /**
     * 获取温度单位符号
     */
    private String getTemperatureUnitSymbol(String unit) {
        switch (unit.toLowerCase().trim()) {
            case "摄氏度":
            case "celsius":
            case "c":
                return "°C";
            case "华氏度":
            case "fahrenheit":
            case "f":
                return "°F";
            case "开尔文":
            case "kelvin":
            case "k":
                return "K";
            default:
                return "";
        }
    }
    
    /**
     * 计算两点之间的距离
     * 
     * @param x1 第一个点的X坐标
     * @param y1 第一个点的Y坐标
     * @param x2 第二个点的X坐标
     * @param y2 第二个点的Y坐标
     * @return 两点之间的距离
     */
    @Tool(description = "计算两点之间的距离")
    public String calculateDistance(
            @ToolParam(description = "第一个点的X坐标") double x1,
            @ToolParam(description = "第一个点的Y坐标") double y1,
            @ToolParam(description = "第二个点的X坐标") double x2,
            @ToolParam(description = "第二个点的Y坐标") double y2) {
        
        double deltaX = x2 - x1;
        double deltaY = y2 - y1;
        double distance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        
        return String.format("""
                距离计算结果:
                点1 (%.2f, %.2f) 和点2 (%.2f, %.2f) 之间的距离是 %.2f 单位
                
                计算公式:
                距离 = √[(x₂ - x₁)² + (y₂ - y₁)²]
                     = √[(%.2f - %.2f)² + (%.2f - %.2f)²]
                     = √[%.2f² + %.2f²]
                     = √%.2f
                     = %.2f
                """, 
                x1, y1, x2, y2, distance,
                x2, x1, y2, y1,
                deltaX, deltaY,
                deltaX * deltaX + deltaY * deltaY,
                distance);
    }

    public static void main(String[] args) {
        SimpleCalculatorService service = new SimpleCalculatorService();
        
        // 测试基本计算
        System.out.println("基本计算测试:");
        System.out.println(service.calculate(10, 5, "加"));
        System.out.println(service.calculate(10, 5, "减"));
        System.out.println(service.calculate(10, 5, "乘"));
        System.out.println(service.calculate(10, 5, "除"));
        
        // 测试温度转换
        System.out.println("\n温度转换测试:");
        System.out.println(service.convertTemperature(25, "摄氏度", "华氏度"));
        
        // 测试BMI计算
        System.out.println("\nBMI计算测试:");
        System.out.println(service.calculateBMI(70, 1.75));
    }
}
